package com.ruoyi.common.utils.flow;

import com.ruoyi.common.core.domain.BaseFlowEntity;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.AuditStatus;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.warm.flow.core.dto.FlowParams;
import com.warm.flow.core.entity.Instance;
import com.warm.flow.core.enums.SkipType;
import com.warm.flow.core.service.InsService;
import com.warm.flow.core.service.TaskService;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author YanWenliang
 * @date 2024/8/27 16:48
 * @desciption: 流程实例创建工具类
 */
public class FlowParamsUtils {

    private static InsService insService = SpringUtils.getBean("instanceService");
    public static <T extends BaseFlowEntity> FlowParams build(T t, String nodeCode){
        LoginUser user = SecurityUtils.getLoginUser();
        FlowParams flowParams = FlowParams.build().createBy(user.getUser().getUserId().toString())
                .nickName(user.getUser().getNickName())
                .skipType(t.getSkipType())
                .nodeCode(nodeCode)
                .message(t.getMessage())
                .signature(t.getSignature());
        List<SysRole> roles = user.getUser().getRoles();

        if (Objects.nonNull(roles)) {
            List<String> roleList = roles.stream().map(role -> "role:" + role.getRoleId()).collect(Collectors.toList());
            roleList.add("user:" + SecurityUtils.getUserId());
            flowParams.permissionFlag(roleList);
        }
        return flowParams;
    }

    /**
     * 开启流程
     * @param t
     * @param flowCode
     * @param id
     * @param <T>
     */
    public static <T extends BaseFlowEntity> void start(T t, String flowCode, String id){
        // 设置流程审批
        FlowParams flowParams = FlowParams.build().flowCode(flowCode)
                .createBy(SecurityUtils.getLoginUser().getUserId().toString())
                .nickName(SecurityUtils.getLoginUser().getUser().getNickName());

        Instance instance = insService.start(id, flowParams);
        t.setInstanceId(instance.getId());
        t.setNodeCode(instance.getNodeCode());
        t.setNodeName(instance.getNodeName());
        t.setFlowStatus(instance.getFlowStatus());
    }


    /**
     * 提交
     * @param <T>
     */
    public static <T extends BaseFlowEntity> void submit(T t){
        t.setSkipType(SkipType.PASS.getKey());
        FlowParams flowParams = FlowParamsUtils.build(t, "");
        FlowParamsUtils.skipByInsId(t, flowParams);
    }

    /**
     * 根据实例id，流程跳转，一般是开始节点后第一个节点，用来提交申请，此时不可有同时两个代办任务
     * @param <T>
     */
    public static <T extends BaseFlowEntity> Instance skipByInsId(T t, FlowParams flowParams){
        Instance instance = insService.skipByInsId(t.getInstanceId(), flowParams);
        t.setNodeCode(instance.getNodeCode());
        t.setNodeName(instance.getNodeName());
        t.setFlowStatus(instance.getFlowStatus());
        return instance;
    }

    /**
     * 节点跳转
     * @param t
     * @param <T>
     */
    public static <T extends BaseFlowEntity> Instance skip(T t, FlowParams flowParams){
        Instance instance = insService.skip(t.getTaskId(), flowParams);
        t.setNodeCode(instance.getNodeCode());
        t.setNodeName(instance.getNodeName());
        t.setFlowStatus(instance.getFlowStatus());
        return instance;
    }


    /**
     * 节点跳转
     *
     * @param t
     * @param <T>
     */
    public static <T extends BaseFlowEntity> void skip(T t, String nodeCode){
        FlowParams flowParams = build(t, nodeCode);
        Instance instance = insService.skip(t.getTaskId(), flowParams);
        t.setNodeCode(instance.getNodeCode());
        t.setNodeName(instance.getNodeName());
        t.setFlowStatus(instance.getFlowStatus());

        if (instance.getFlowStatus() == 8){
            t.setAuditStatus(flowParams.getSkipType().equals("PASS") ? AuditStatus.PASS.getCode() : AuditStatus.NOT_PASS.getCode());
        } else {
            t.setAuditStatus(AuditStatus.IN_AUDIT.getCode());
        }
    }

    /**
     * 删除流程实例
     * @param id
     * @return
     */
    public static boolean remove(Long ...id){
        List<Long> ids = Arrays.asList(id);
        return insService.remove(ids);
    }

    /**
     * 删除流程实例
     * @return
     */
    public static boolean remove(List<Long> ids){
        return insService.remove(ids);
    }

}
